﻿namespace Leetcode.N0076;

public class Solution
{
    public string MinWindow(string s, string t)
    {
        var tLettersCount = new LettersCounter();
        foreach (var item in t)
        {
            tLettersCount[item]++;
        }
        var sLettersCount = new LettersCounter();
        var findCountOfT = 0;
        var minLength = int.MaxValue;
        var findValue = string.Empty;
        var sIndexRight = 0;
        var queue = new Queue<int>();

        while (true)
        {
            for (; sIndexRight < s.Length && findCountOfT < t.Length; sIndexRight++)
            {
                var sLetter = s[sIndexRight];
                if (tLettersCount[sLetter] == 0)
                {
                    continue;
                }
                queue.Enqueue(sIndexRight);
                sLettersCount[sLetter]++;
                if (sLettersCount[sLetter] <= tLettersCount[sLetter])
                {
                    findCountOfT++;
                }
            }

            if (findCountOfT < t.Length)
            {
                return findValue;
            }

            while (findCountOfT >= t.Length)
            {
                var sIndexLeft = queue.Dequeue();
                var sLetterLeft = s[sIndexLeft];
                sLettersCount[sLetterLeft]--;

                if (sLettersCount[sLetterLeft] < tLettersCount[sLetterLeft])
                {
                    findCountOfT--;
                }

                var length = sIndexRight - sIndexLeft;
                if (length >= minLength)
                {
                    continue;
                }
                minLength = length;
                findValue = s.Substring(sIndexLeft, length);
            }
        }
    }
}

public class LettersCounter
{
    private int[] counts = new int[52];

    public int this[char c]
    {
        get
        {
            int index = (c > 'Z') ? (int)(c - 'a') + 26 : (int)(c - 'A');
            return this.counts[index];
        }
        set
        {
            int index = (c > 'Z') ? (int)(c - 'a') + 26 : (int)(c - 'A');
            this.counts[index] = value;
        }
    }
}
